//
//  NEDWebViewController.m
//  MoreCoin
//
//  Created by tete on 2019/8/15.
//  Copyright © 2019 MoreCoin. All rights reserved.
//

#import "NEDWebViewController.h"
#import <KVOController/KVOController.h>
#import "UIColor+NEDStyle.h"
#import "NEDDefines.h"
#import "NEDConstant.h"
#import "UIColor+NEDStyle.h"
#import "UIFont+NED.h"
#import <Masonry/Masonry.h>
#import "UIViewController+NEDBase.h"
#import "NEDApp+Mediator.h"
#import "NSString+NED.h"
#import <YYCategories/NSString+YYAdd.h>
#import <FDFullscreenPopGesture/UINavigationController+FDFullscreenPopGesture.h>
#import "UIViewController+NEDCallBack.h"

typedef NS_ENUM(NSInteger, NEDWebViewClickCallBackEventID) {
    NEDWebViewClickCallBackEventID_None,
    /// 优惠券
    NEDWebViewClickCallBackEventID_Coupon,
};

NEDWebViewClickCallBackEventID NEDWebViewClickCallBackEventIDByDes(NSString * ID){
    if([ID isEqualToString:@"coupon"])  return NEDWebViewClickCallBackEventID_Coupon;
    
    return NEDWebViewClickCallBackEventID_None;
}

/// 同步获取方法
NSString * const NEDWebViewGetFunc = @"nedGetFunc";
/// 获取应用信息
NSString * const NEDWebViewFuncAppInfo = @"appInfo";

@interface NEDWebViewController () <WKNavigationDelegate, WKUIDelegate, WKScriptMessageHandler>

@property (strong, nonatomic, readwrite) WKWebView * webView;
@property (strong, nonatomic) UIProgressView *progressView;

@property (strong, nonatomic) WKWebViewJavascriptBridge *bridge;

@end

@implementation NEDWebViewController

//  url 包含中文的问题
- (NSString *)fixURL:(NSString *)url {
    url= [url stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    NSString *tempSTR = @"*S&S^@)MS&@HH%D^#@*#*^@";
    url = [url stringByReplacingOccurrencesOfString:@"://"
                                         withString:tempSTR];
    for (NSInteger i = 10; i > 1; i --) {
        NSString *separa = @"";
        for (NSInteger j = 0 ; j < i; j ++) {
            separa = [separa stringByAppendingString:@"/"];
        }
        url = [url stringByReplacingOccurrencesOfString:separa
                                             withString:@"/"];
    }
    url = [url stringByReplacingOccurrencesOfString:tempSTR
                                         withString:@"://"];
    
    url = [url stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    
    return url;
}


- (void)ned_routerLoadParams:(NSDictionary * _Nullable)parameters{
    if(![parameters isKindOfClass:[NSDictionary class]]){
        return;
    }
    id obj = parameters[@"url"];
    if(obj && [obj isKindOfClass:[NSString class]]){
        NSString * url = obj;
        if(url.ned_isURL){
            self.url = [self fixURL:obj];
        }else{
            self.url = [obj stringByURLDecode];
        }
    }
    obj = parameters[@"htmlString"];
    if (obj && ![obj isKindOfClass:[NSNull class]]){
        self.htmlString = obj;
    }
    
    obj = parameters[@"initJsonParams"];
    if (obj && ![obj isKindOfClass:[NSNull class]]){
        self.appInfoAppendJsonParames = obj;
    }
    
    //如果不是URL地址的 不做导航条处理 使用默认的
    if(!self.url || !self.url.ned_isURL){
        return;
    }
    obj = parameters[@"navTitle"];
    if (obj && ![obj isKindOfClass:[NSNull class]]){
        self.navTitle = obj;
    }
    obj = parameters[@"title"];
    if (obj && ![obj isKindOfClass:[NSNull class]]){
        self.navTitle = obj;
    }
    obj = parameters[@"isShowTitleBar"];
    if (obj && ![obj isKindOfClass:[NSNull class]]){
        BOOL sw = [obj boolValue];
        self.isShowTitleBar = @(sw);
    }
    obj = parameters[@"statusBarBgColor"];
    if (obj && ![obj isKindOfClass:[NSNull class]]){
        self.statusBarBgColor = obj;
    }
    obj = parameters[@"statusBarFontBlack"];
    if (obj && ![obj isKindOfClass:[NSNull class]]){
        BOOL sw = [obj boolValue];
        self.statusBarFontBlack = @(sw);
    }
}

- (instancetype)initWithURL:(NSString *)url{
    self = [super init];
    if(self){
        self.url = url;
    }
    return self;
}
- (instancetype)initWithHTMLString:(NSString *)htmlString{
    self = [super init];
    if(self){
        self.htmlString = htmlString;
    }
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.automaticallyAdjustsScrollViewInsets = NO;
    
    [self.progressView setProgress:0.05 animated:YES];
        
    if([self ned_navcHiddenBackBarItem]){
        self.fd_prefersNavigationBarHidden = YES;
    }
    
    /** 监听加载进度 */
    WS(weakSelf);
    [self.KVOController observe:self.webView keyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew block:^(id  _Nullable observer, id  _Nonnull object, NSDictionary<NSString *,id> * _Nonnull change) {
        [weakSelf.progressView setProgress:weakSelf.webView.estimatedProgress animated:YES];
        if (weakSelf.progressView.progress == 1) {
            weakSelf.progressView.hidden = YES;
        } else if (weakSelf.progressView > 0) {
            weakSelf.progressView.hidden = NO;
        }
    }];
    
    if(![self ned_navcIsTransucent]){
        if(IsNonNull(self.navTitle)){
            self.title = self.navTitle;
        }else{
            [self.KVOController observe:self.webView keyPath:@"title" options:NSKeyValueObservingOptionNew block:^(id  _Nullable observer, id  _Nonnull object, NSDictionary<NSString *,id> * _Nonnull change) {
                weakSelf.title = change[NSKeyValueChangeNewKey];
            }];
        }
    }
    
    /// MARK: load
    if (self.url && self.url.ned_isURL){
        NSString * url = self.url;
        if([url containsString:@"?"]){
            url = url.add(@"&");
        }else{
            url = url.add(@"?");
        }
        url = url.add([NSString stringWithFormat:@"temp=%ld",(long)([[NSDate date] timeIntervalSince1970])]);
        NSLog(@"webview URL : %@",url);
        
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:20.0];
        [self.webView loadRequest:request];
    }else if (self.htmlString) {
        [self.webView loadHTMLString:self.htmlString baseURL:nil];
    }else{
        if(self.url){
            if(APP.mediator && [APP.mediator.delegateHUD respondsToSelector:@selector(hud_showMessage:)]){
                [APP.mediator.delegateHUD hud_showMessage:[NSString stringWithFormat:@"网页链接显示异常URL=%@",self.url]];
            }
        }
        if(!self.url && !self.htmlString){
            if(APP.mediator && [APP.mediator.delegateHUD respondsToSelector:@selector(hud_showMessage:)]){
                [APP.mediator.delegateHUD hud_showMessage:@"未获取到URL和HTML的相关信息"];
            }
        }
        self.progressView.hidden = YES;
    }
}

/// 导航条透明
- (BOOL)ned_navcIsTransucent{
    if(self.isShowTitleBar){
        BOOL isTransucent = ![self.isShowTitleBar boolValue];
        
        return isTransucent;
    }
    return [super ned_navcIsTransucent];
}
-(BOOL)ned_navcHiddenBackBarItem{
    BOOL hiddenBack = NO;
    if(self.isShowTitleBar){
        hiddenBack = ![self.isShowTitleBar boolValue];
    }else{
        hiddenBack = [super ned_navcHiddenBackBarItem];
    }
    if(hiddenBack){
        /// 返回按钮网页中自己显示，无导航条下 不遮挡导航条位置操作
        self.navigationController.navigationBar.userInteractionEnabled = NO;
    }
    return hiddenBack;
}
/// 导航条颜色
- (UIColor *)ned_navcBackgroundColor{
    if(self.statusBarBgColor){
        UIColor * color = [UIColor ned_colorWithHexString:self.statusBarBgColor];
        if(color){
            return color;
        }
    }
    return [super ned_navcBackgroundColor];
}
/// 导航条字体颜色
- (UIColor *)ned_navcTitleColor{
    if(self.statusBarFontBlack){
        if([self.statusBarFontBlack boolValue]){
            return [UIColor ned_black];
        }
        return [UIColor ned_white];
    }
    return [super ned_navcTitleColor];
}

- (void)ned_navcBackEvent {
    if ([self.webView canGoBack]) {
        [self.webView goBack];
    }else {
        [self ned_viewcontrollerClose];
    }
}

#pragma mark - delegate webview

- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {

}

- (void)webView:(WKWebView *)webView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error{
    
}

#pragma mark - WKScriptMessageHandler
- (void)userContentController:(WKUserContentController *)userContentController
      didReceiveScriptMessage:(WKScriptMessage *)message {
    [self webCallNav:message.name params:message.body];
}

- (void)webCallNav:(NSString *)message  params:(NSString *)params{
    
}


#pragma mark - webview UI

- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
    [alertController addAction:([UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler();
    }])];
    [self presentViewController:alertController animated:YES completion:nil];
    
}
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler{
    //    DLOG(@"msg = %@ frmae = %@",message,frame);
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
    [alertController addAction:([UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(NO);
    }])];
    [alertController addAction:([UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(YES);
    }])];
    [self presentViewController:alertController animated:YES completion:nil];
}
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler{
    if ([prompt isEqualToString:NEDWebViewGetFunc]) {
        //获取应用信息
        if ([defaultText isEqualToString:NEDWebViewFuncAppInfo]) {
            if(completionHandler){
                completionHandler(self.__nedWebviewAppInfo);
            }
        }
        return;
    }
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:prompt message:@"" preferredStyle:UIAlertControllerStyleAlert];
    [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
        textField.text = defaultText;
    }];
    [alertController addAction:([UIAlertAction actionWithTitle:@"完成" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(alertController.textFields[0].text?:@"");
    }])];
    [self presentViewController:alertController animated:YES completion:nil];
}


#pragma mark - getter
- (UIProgressView *)progressView {
    if (!_progressView) {
        _progressView = [[UIProgressView alloc] initWithFrame:CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width, 10.0f)];
        _progressView.backgroundColor = [[UIColor ned_background] lighterColor:0.9];
        _progressView.progressTintColor = [UIColor ned_blue];
        _progressView.progress = 0.0;
        [self.webView addSubview:_progressView];
        [_progressView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.right.top.equalTo(self.webView);
            make.height.mas_equalTo(2);
        }];
    }
    return _progressView;
}

-(WKWebView *)webView{
    if(_webView){
        return _webView;
    }
    
    WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
    // 创建设置对象
    WKPreferences *preferences = [[WKPreferences alloc]init];
    preferences.javaScriptEnabled = YES;
    config.preferences = preferences;
    
    //这个类主要用来做native与JavaScript的交互管理
    WKUserContentController *wkUController = [[WKUserContentController alloc] init];
    config.userContentController = wkUController;
    
//    注入本地js脚本（使js和native交互方法统一）
    
    NSString *jsSource = [NSString stringWithContentsOfFile:[[NSBundle bundleForClass:NEDWebViewController.class] pathForResource:@"webviewJSBridge" ofType:@"js"] encoding:NSUTF8StringEncoding error:nil];
    WKUserScript *script = [[WKUserScript alloc] initWithSource:jsSource injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES];
    [config.userContentController addUserScript:script];
    
    _webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height) configuration:config];
    _webView.navigationDelegate = self;
    _webView.UIDelegate = self;
    _webView.backgroundColor = [UIColor clearColor];
    _webView.scrollView.backgroundColor = [UIColor clearColor];
    _webView.opaque = NO;
    _webView.backgroundColor = [UIColor ned_background];
    _webView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    [self.view addSubview:_webView];
    [_webView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.equalTo(self.view);
    }];
    if (@available(iOS 11.0, *)) {
        _webView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
    }
    [self registerWebViewJavascriptHander];
    return _webView;
}

#pragma mark - 注册js 方法

- (void)registerWebViewJavascriptHander{
    
    [WKWebViewJavascriptBridge enableLogging];
    _bridge = [WKWebViewJavascriptBridge bridgeForWebView:self.webView];
    [_bridge setWebViewDelegate:self];
    
    WS(weakSelf)
    //获取应用信息
    [_bridge registerHandler:@"appInfo" handler:^(id data, WVJBResponseCallback responseCallback){
        if(responseCallback){
            responseCallback(weakSelf.__nedWebviewAppInfo);
        }
    }];
    
    //关闭页面
    [_bridge registerHandler:@"closeWeb" handler:^(id data, WVJBResponseCallback responseCallback) {
        if (weakSelf.navigationController.topViewController == weakSelf){
            [weakSelf.navigationController popViewControllerAnimated:YES];
        }else{
            [weakSelf dismissViewControllerAnimated:YES completion:nil];
        }
    }];
    
    // 刷新页面 （预留）
    [_bridge registerHandler:@"reloadH5" handler:^(id data, WVJBResponseCallback responseCallback) {
        NSLog(@"%@", data);
        [weakSelf.webView reload];
    }];
    
    //后退操作
    [_bridge registerHandler:@"goBack" handler:^(id data, WVJBResponseCallback responseCallback) {
        [weakSelf ned_navcBackEvent];
    }];
    
    //截取后退监听操作 1:设置拦截 2:取消拦截（预留）
    [_bridge registerHandler:@"isInterceptBack" handler:^(id data, WVJBResponseCallback responseCallback) {
        NSLog(@"%@", data);
    }];
    
    //打开新的H5页面（预留）
    [_bridge registerHandler:@"secondaryPage" handler:^(id data, WVJBResponseCallback responseCallback) {
        if(![data isKindOfClass:[NSDictionary class]]){
            return;
        }
        if(APP.mediator.delegateJSWebView &&
           [APP.mediator.delegateJSWebView respondsToSelector:@selector(jsWebView_openNextWebURL:title:)]){
            NSString * url = data[@"url"];
            NSString * title = data[@"title"];
            if(IsNonNull(url)){
                [APP.mediator.delegateJSWebView jsWebView_openNextWebURL:url title:title];
            }
        }
    }];
    
    //上报埋点
    [_bridge registerHandler:@"postPointInfo" handler:^(id data, WVJBResponseCallback responseCallback) {
        if(![data isKindOfClass:[NSDictionary class]]){
            return;
        }
        if(APP.mediator.delegateJSWebView &&
           [APP.mediator.delegateJSWebView respondsToSelector:@selector(jsWebView_postPointEventID:properties:)]){
            NSString *eventId = data[@"eventId"];
            NSString *msg = data[@"msg"];
            NSMutableDictionary *dict = [NSMutableDictionary dictionary];
            dict[@"msg"] = msg;
            if(IsNonNull(eventId)){
                [APP.mediator.delegateJSWebView jsWebView_postPointEventID:eventId properties:dict];
            }
        }
    }];
    
    //跳转到原生页面
    [_bridge registerHandler:@"routerPath" handler:^(id data, WVJBResponseCallback responseCallback) {
        if(![data isKindOfClass:[NSString class]]){
            return;
        }
        if(IsNonNull(data) &&
           APP.mediator.delegateJSWebView &&
           [APP.mediator.delegateJSWebView respondsToSelector:@selector(jsWebView_openInnerAppSchemeURL:)]){
            [APP.mediator.delegateJSWebView jsWebView_openInnerAppSchemeURL:data];
        }
    }];
    
    // 提示（预留）
    [_bridge registerHandler:@"toast" handler:^(id data, WVJBResponseCallback responseCallback) {
        NSString * message = @"";
        if([data isKindOfClass:[NSString class]]){
            message = data;
        }else if ([data isKindOfClass:[NSDictionary class]]){
            message = data[@"message"];
        }
        if(IsNonNull(message) &&
           APP.mediator.delegateJSWebView &&
           [APP.mediator.delegateJSWebView respondsToSelector:@selector(jsWebView_showMessageToast:)]){
            [APP.mediator.delegateJSWebView jsWebView_showMessageToast:message];
        }
    }];
    
    // 点击回调
    [_bridge registerHandler:@"clickCallback" handler:^(id data, WVJBResponseCallback responseCallback) {
        if (![data isKindOfClass:[NSDictionary class]]){
            NSLog(@"===== H5点击回调的数据：%@",data);
            return;
        }
        NEDWebViewClickCallBackEventID eventID = NEDWebViewClickCallBackEventIDByDes(data[@"eventId"]);
        NSString * jsonInfo = data[@"msg"];
        [weakSelf __nedWebview_clickEvent:eventID jsonInfo:jsonInfo];
    }];
    
    [self nedWebview_registJSBridge:_bridge];
}

- (NSString *)__webviewObjToJsonString:(id)obj{
    NSData * jsonData = [NSJSONSerialization dataWithJSONObject:obj options:0 error:NULL];
    NSString * jsonString = @"";
    if(jsonData && jsonData.length > 0){
        jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    }
    return jsonString;
}

- (NSString *)__nedWebviewAppInfo{
    if(APP.mediator.delegateJSWebView &&
       [APP.mediator.delegateJSWebView respondsToSelector:@selector(jsWebView_appInfo)]){
        NSMutableDictionary * dic = [NSMutableDictionary dictionaryWithDictionary:[APP.mediator.delegateJSWebView jsWebView_appInfo]];
        [dic addEntriesFromDictionary:self.nedWebview_appendAppInfo];
        return [self __webviewObjToJsonString:dic];
    }
    return @"";
}

- (void)__nedWebview_clickEvent:(NEDWebViewClickCallBackEventID)eventID jsonInfo:(id)jsonInfo{
    
    if(eventID == NEDWebViewClickCallBackEventID_Coupon){
        if(self.ned_callback){
            self.ned_callback(self,jsonInfo);
        }
    }
}

/// 需要附加的APPInfo信息
- (NSMutableDictionary *)nedWebview_appendAppInfo{
    NSMutableDictionary * appendInfo = [NSMutableDictionary new];
    if(self.appInfoAppendJsonParames){
        appendInfo[@"initJsonParams"] = [self __webviewObjToJsonString:self.appInfoAppendJsonParames];
    }
    return appendInfo;
}
/// 注册其他的JS方法
- (void)nedWebview_registJSBridge:(WKWebViewJavascriptBridge *)bridge{
    
}


@end
